/*
 * File: Viewer.java
 * Author: Bill Hamilton and Sarah Gray
 * Viewer is the main GUI to the project you may authenticate to flickr, browse the journal,
 *  and upload photo's. 
*/
import java.awt.Canvas;
import java.awt.FileDialog;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.Desktop;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Hashtable;
import java.util.TreeMap;
import java.util.TreeSet;

import javax.swing.ImageIcon;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import javax.xml.parsers.ParserConfigurationException;

import javax.imageio.*;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import com.aetrion.flickr.Flickr;
import com.aetrion.flickr.FlickrException;
import com.aetrion.flickr.REST;
import com.aetrion.flickr.RequestContext;
import com.aetrion.flickr.auth.Auth;
import com.aetrion.flickr.auth.AuthInterface;
import com.aetrion.flickr.auth.Permission;

public class Viewer extends javax.swing.JFrame implements TreeSelectionListener{
    
    /** Creates new form Viewer */
    public Viewer() {
        initComponents();
    }
       
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        treeTop = new DefaultMutableTreeNode("Travel Journal");
        tripTree = new javax.swing.JTree(treeTop);
        tripTree.addTreeSelectionListener(this);
        
        rootNode = new DefaultMutableTreeNode(journalString);
        treeModel = new DefaultTreeModel(rootNode);
        tripTree.setModel(treeModel);
        tripTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        
        viewPane = new javax.swing.JEditorPane();
        viewPane.setEditable(false);
        scrollPane = new JScrollPane();
        authLabel = new javax.swing.JLabel();
        pictureCanvas = new MyPictureCanvas();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        popupMenu = new javax.swing.JPopupMenu();
        OpenMenuItem = new javax.swing.JMenuItem();
        AuthenticateMenuItem = new javax.swing.JMenuItem();
        UploadMenuItem1 = new javax.swing.JMenuItem();
        UploadMenuItem2 = new javax.swing.JMenuItem();
        ClearSearchsMenuItem = new javax.swing.JMenuItem();
        QuitMenuItem = new javax.swing.JMenuItem();
        searchField = new java.awt.TextField();
        searchButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Tour De Flickr"); // NOI18N
        setName("Form"); // NOI18N
        setResizable(false);

        jScrollPane1.setName("jScrollPane1"); // NOI18N

        tripTree.setName("tripTree"); // NOI18N
        tripTree.addMouseListener(new PopupListener());
        jScrollPane1.setViewportView(tripTree);

        viewPane.setContentType("text/html");
        viewPane.setName("viewPane"); // NOI18N
        viewPane.addMouseListener(new PopupListener());
                
        scrollPane.setViewportView(viewPane);
        //scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        authLabel.setText("Authentication Status: Not Signed In"); // NOI18N
        authLabel.setName("authLabel"); // NOI18N
        
       
        pictureCanvas.setName(""); // NOI18N
        setImage(flickrPic);
        
        jMenuBar1.setName("jMenuBar1"); // NOI18N

        jMenu1.setText("File"); // NOI18N
        jMenu1.setName("jMenu1"); // NOI18N

        OpenMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK));
        OpenMenuItem.setText("Open"); // NOI18N
        OpenMenuItem.setName("OpenMenuItem"); // NOI18N
        OpenMenuItem.addActionListener(new OpenListener(this));
        jMenu1.add(OpenMenuItem);

        AuthenticateMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_T, java.awt.event.InputEvent.CTRL_MASK));
        AuthenticateMenuItem.setText("Authenticate"); // NOI18N
        AuthenticateMenuItem.setName("AuthenticateMenuItem"); // NOI18N
        AuthenticateMenuItem.addActionListener(new AuthListener(this));
        jMenu1.add(AuthenticateMenuItem);

        UploadMenuItem1.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_U, java.awt.event.InputEvent.CTRL_MASK));
        UploadMenuItem1.setText("Upload"); // NOI18N
        UploadMenuItem1.setName("UploadMenuItem1"); // NOI18N
        UploadMenuItem1.setEnabled(false);
        UploadMenuItem1.addActionListener(new UploadListener(this));
        jMenu1.add(UploadMenuItem1);
        
        UploadMenuItem2.setText("Upload"); // NOI18N
        UploadMenuItem2.setName("UploadMenuItem2"); // NOI18N
        UploadMenuItem2.setEnabled(false);
        UploadMenuItem2.addActionListener(new UploadListener(this));
        popupMenu.add(UploadMenuItem2);  
        
        ClearSearchsMenuItem.setText("Clear Search Results");
        ClearSearchsMenuItem.setEnabled(false);
        ClearSearchsMenuItem.addActionListener(new ClearListener(this));
        jMenu1.add(ClearSearchsMenuItem);
        
        QuitMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, java.awt.event.InputEvent.CTRL_MASK));
        QuitMenuItem.setText("Quit"); // NOI18N
        QuitMenuItem.setName("QuitMenuItem"); // NOI18N
        QuitMenuItem.addActionListener(new CloseListener());
        jMenu1.add(QuitMenuItem);

        jMenuBar1.add(jMenu1);

        searchField.setName("searchField"); // NOI18N
        searchField.setText(""); // NOI18N" +
        searchField.addKeyListener(new SearchReturnListener());

        searchButton.setText("Search"); // NOI18N
        searchButton.setName("searchButton"); // NOI18N
        searchButton.addActionListener(new SearchListener(this));
        
        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 179, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(scrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 561, Short.MAX_VALUE)
                            .addComponent(pictureCanvas, javax.swing.GroupLayout.DEFAULT_SIZE, 561, Short.MAX_VALUE)))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(authLabel)
                        .addGap(190, 190, 190)
                        .addComponent(searchField, javax.swing.GroupLayout.PREFERRED_SIZE, 310, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(searchButton, javax.swing.GroupLayout.DEFAULT_SIZE, 94, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(pictureCanvas, javax.swing.GroupLayout.DEFAULT_SIZE, 381, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(scrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 244, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 631, Short.MAX_VALUE))
                .addGap(10, 10, 10)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(authLabel)
                    .addComponent(searchButton)
                    .addComponent(searchField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        pack();

    }// </editor-fold>//GEN-END:initComponents

    //listener which exits program
    public class CloseListener implements ActionListener
    {
    	public void actionPerformed(ActionEvent e)
    	{
    		System.exit(0);
    	}
    }
    
    //listens for action requiring authentication to happen
    public class AuthListener implements ActionListener
    {
    	Viewer parent;
    	public AuthListener(Viewer _parent)
    	{
    		parent = _parent;
    	}
		public void actionPerformed(ActionEvent arg0) {
			parent.authToFlickr();
		}
    }
    
    //listens for search button to be pressed
    public class SearchListener implements ActionListener
    {
    	Viewer parent;
    	public SearchListener(Viewer _parent)
    	{
    		parent = _parent;
    	}
		public void actionPerformed(ActionEvent arg0) {
			parent.performSearch();
		}
    }
    
    //listens for return to be pressed in search bar
    public class SearchReturnListener implements KeyListener
    {
		public void keyPressed(KeyEvent arg0) {}

		public void keyReleased(KeyEvent arg0) {}

		public void keyTyped(KeyEvent arg0)
		{
			if(arg0.getKeyChar() == '\n')
				performSearch();
		}
    }
    
    private void performSearch()
    {
    	synchronized (this)
    	{
	    	String searchString = searchField.getText().trim();
			if(searchHash != null && !searchHash.containsKey(searchString))
			{
				TreeSet<HtmlAble> list = journal.doSearch(searchString);
				DefaultMutableTreeNode tmpNode = new JTree.DynamicUtilTreeNode(searchString,list.toArray());
				searchNode.add(tmpNode);
				searchHash.put(searchString,list);
				treeModel.reload();
				tripTree.setSelectionPath(new TreePath(tmpNode.getPath()));
			}
    	}
    }
    
    //listens for a search result clear action
    public class ClearListener implements ActionListener
    {
    	Viewer parent;
    	public ClearListener(Viewer _parent)
    	{
    		parent = _parent;
    	}
		public void actionPerformed(ActionEvent arg0) {
			synchronized (parent)
			{
				searchNode.removeAllChildren();
				searchHash.clear();
				treeModel.reload();
			}
		}
    }
    
    class PopupListener extends MouseAdapter {
        public void mousePressed(MouseEvent e) {
            maybeShowPopup(e);
        }

        public void mouseReleased(MouseEvent e) {
            maybeShowPopup(e);
        }

        private void maybeShowPopup(MouseEvent e) {
            if (e.isPopupTrigger()) {
                popupMenu.show(e.getComponent(),
                           e.getX(), e.getY());
            }
        }
    }
    
    //Opens a new xml document and reloads the GUI and hashtables
    public class OpenListener implements ActionListener
    {
    	Viewer parent;
    	public XMLFilter filter = new XMLFilter();
    	public OpenListener(Viewer _parent)
    	{
    			parent = _parent;
    	}
    	
    	public class XMLFilter implements FilenameFilter
    	{
    		public boolean accept(File dir, String name)
    		{
    			return name.toLowerCase().matches(".*\\.xml");
    		}
    	}
    	
    	public void actionPerformed(ActionEvent e)
    	{
    		synchronized (parent)
    		{
    			tripTree.removeTreeSelectionListener(parent);
    			FileDialog openDialog = new FileDialog(parent,"Open Journal",FileDialog.LOAD);
    			openDialog.setFilenameFilter(filter);
    			openDialog.show();
    			if(openDialog.getFile() == null)
    				return;
    			Picture.parentFile = new File(openDialog.getFile());
    			String filename = openDialog.getFile();
    			if(filename == null || !filename.toLowerCase().matches(".*\\.xml"))
    			{
    				System.err.println("Pick a valid File Please!");
    				return;
    			}
    			System.out.println(filename);
    			HelperMethods hm = new HelperMethods();
                Document d = hm.createParser(filename);
                hm.parseFile(d);
                journal=hm.tj;

                //setup tree
                rootNode.removeAllChildren();
                HtmlAble[] pics = new HtmlAble[journal.getPictures().size()];
                journal.getPictures().toArray(pics);
                Arrays.sort(pics);
                rootNode.add(new JTree.DynamicUtilTreeNode(picturesString,pics));
                
                //add photos sorted by album
                DefaultMutableTreeNode albumsNode = new DefaultMutableTreeNode(albumsString);
                rootNode.add(albumsNode);
                albumHash = journal.buildAlbumMap();
                for(String album : albumHash.keySet())
                {
                	albumsNode.add(new JTree.DynamicUtilTreeNode(album,albumHash.get(album).toArray()));
                }
                
                //add entries sorted by location
                DefaultMutableTreeNode locationsNode = new DefaultMutableTreeNode(locationsString);
                rootNode.add(locationsNode);
                locationHash = journal.buildLocationMap();
                for(String location : locationHash.keySet())
                {
                	locationsNode.add(new JTree.DynamicUtilTreeNode(location,locationHash.get(location).toArray()));
                }
                
                //add entries sorted by place
                DefaultMutableTreeNode placesNode = new DefaultMutableTreeNode(placesString);
                rootNode.add(placesNode);
                placesHash = journal.buildPlaceMap();
                for(String place : placesHash.keySet())
                {
                	placesNode.add(new JTree.DynamicUtilTreeNode(place,placesHash.get(place).toArray()));
                }
                
                //add entries sorted by people
                DefaultMutableTreeNode peopleNode = new DefaultMutableTreeNode(peopleString);
                rootNode.add(peopleNode);
                peopleHash = journal.buildPersonMap();
                for(String person : peopleHash.keySet())
                {
                	peopleNode.add(new JTree.DynamicUtilTreeNode(person,peopleHash.get(person).toArray()));
                }
                
                //add entries sorted by dates
                DefaultMutableTreeNode datesNode = new DefaultMutableTreeNode(dateString);
                rootNode.add(datesNode);
                datesHash = journal.buildDateMap();
                for(Picture.MyDate date : datesHash.keySet())
                {
                	datesNode.add(new JTree.DynamicUtilTreeNode(date,datesHash.get(date).toArray()));
                }
                
                rootNode.add(new JTree.DynamicUtilTreeNode(plansString,journal.getPlans().getMakeup().toArray()));
                
                searchNode = new DefaultMutableTreeNode("Search Results");
                searchNode.setAllowsChildren(true);
                rootNode.add(searchNode);
                searchHash = new TreeMap<String, Collection<HtmlAble>>();
                
                treeModel.reload();
                tripTree.addTreeSelectionListener(parent);
                tripTree.setSelectionPath(tripTree.getPathForRow(0));
                searchButton.setEnabled(true);
                ClearSearchsMenuItem.setEnabled(true);
    		}
    	}
    }
    
    //listens for when a widget to upload something is clicked
    public class UploadListener implements ActionListener
    {
    	Viewer parent;
    	public UploadListener(Viewer _parent)
    	{
    		parent = _parent;
    	}
    	
    	public void actionPerformed(ActionEvent e)
    	{
    		synchronized (parent)
    		{
	    		if(!authenticated)
	     			authToFlickr();
	    		if(!authenticated)
	    			return;
	  
	    		Picture selectedPic = null;
	    		if(selectedNode instanceof Picture)
	    		{
	    			selectedPic = (Picture)selectedNode;
	    		}
	    		else
	    			return;
	    		UploadFrame uploader = new UploadFrame(selectedPic,myFlickr,parent);
	    		uploader.setVisible(true);
    		}
    	}
    }
    
    //sets all upload clickables to be able to upload
    private void setUploadEnabled(boolean isEnabled)
    {
    	UploadMenuItem1.setEnabled(isEnabled);
    	UploadMenuItem2.setEnabled(isEnabled);
    }
    
    //tree call back
    public void valueChanged(TreeSelectionEvent e) {
		synchronized (this)
		{
	    	DefaultMutableTreeNode node = (DefaultMutableTreeNode) tripTree.getLastSelectedPathComponent();
			if(node == null)
				return;
	    	selectedNode = node.getUserObject();
	    	setUploadEnabled(false);
			if(selectedNode instanceof Picture)
			{
				Picture selectedPicture = (Picture)selectedNode;
				if(selectedPicture.getURI() != null)
				{
					setUploadEnabled(true);
					setImage(selectedPicture.getURI());
				}
				else
				{
					setImage(errorPic);
				}
				resetText(selectedPicture.getHTML());
			}
			else if(selectedNode instanceof TravelPlansMakeup)
			{
				TravelPlansMakeup selectedMakeup = (TravelPlansMakeup) selectedNode;
				resetText(selectedMakeup.getHTML());
				setImage(flickrPic);
			}
			else if(selectedNode instanceof Picture.MyDate && datesHash.containsKey(selectedNode))
			{
					resetText(HtmlAble.getHTML(datesHash.get(selectedNode)));
			}
			//see what branch was selected and reset text to appropriate html
			else if(selectedNode instanceof String)
			{
				setImage(flickrPic);
				String selectedString = (String) selectedNode;
				if(selectedString == journalString && journal != null)
					resetText(journal.getHTML());
				else if(selectedString == picturesString)
					resetText(HtmlAble.getHTML(journal.getPictures()));
				else if(selectedString == plansString)
					resetText(journal.getPlans().getHTML());
				else if(albumHash != null && albumHash.containsKey(selectedString))
				{
					resetText(HtmlAble.getHTML(albumHash.get(selectedString)));
				}
				else if(locationHash != null && locationHash.containsKey(selectedString))
				{
					resetText(HtmlAble.getHTML(locationHash.get(selectedString)));
				}
				else if(peopleHash != null && peopleHash.containsKey(selectedString))
				{
					resetText(HtmlAble.getHTML(peopleHash.get(selectedString)));
				}
				else if(searchHash != null && searchHash.containsKey(selectedString))
				{
					resetText(HtmlAble.getHTML(searchHash.get(selectedString)));
				}
				
			}
		}
	}
    
    //functions to set canvas's pic
    private void setImage(URI uri)
    {
    	try {
			ImageIcon image = new ImageIcon(uri.toURL());
			pictureCanvas.setImage(image.getImage());
		} catch (MalformedURLException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
    }
    
    private void setImage(ImageIcon image)
    {
    	pictureCanvas.setImage(image.getImage());
    }
    
    
    //canvas that displays a scaled image
    public class MyPictureCanvas extends Canvas
    {
    	public Image img;
    	public synchronized void paint(Graphics g)
    	{	if(img != null)
    		{
    			int imgWidth = img.getWidth(this);
	    		int imgHeight = img.getHeight(this);
	    		double widthScale = imgWidth/this.getWidth();
	    		double heigthScale = imgHeight/this.getHeight();
	    		double scale = Math.min(1.0,1.0/Math.max(widthScale,heigthScale));
	    		imgWidth *= scale;
	    		imgHeight *= scale;
	    		int dstx = this.getWidth()/2-imgWidth/2;
	    		int dsty = this.getHeight()/2-imgHeight/2;
	    		g.drawImage(img,dstx,dsty,dstx+imgWidth,dsty+imgHeight,0,0,img.getWidth(this),img.getHeight(this),this);
    		}
       	}

    	public void setImage(Image _img)
    	{
    		synchronized (this)
    		{
    			img = _img;
    		}
    		repaint();
    	}
    	
    }
    
    //implements the authentication procedure
    private void authToFlickr()
    {
    	synchronized (this)
    	{
    		try {
				myFlickr = new Flickr("340861ea34c0d0317a28426c2a87e388", new REST());
			} catch (ParserConfigurationException e2) {
				System.err.println(e2.getMessage());
			}
            Flickr.debugStream = false;
            // Set the shared secret which is used for any calls which require signing.
            requestContext = RequestContext.getRequestContext();
            requestContext.setSharedSecret("14b4691dcfcf386c");
            AuthInterface authInterface = myFlickr.getAuthInterface();
            String frob = "";
            try {
                frob = authInterface.getFrob();
            } catch (Exception e) {
                System.err.println(e.getMessage());
                return;
            }
            System.out.println("frob: " + frob);

        	URL url = null;
			try {
				url = authInterface.buildAuthenticationUrl(Permission.WRITE, frob);
			} catch (MalformedURLException e1) {
				System.out.println(e1.getMessage());
				return;
			}

			System.out.println(url.toExternalForm());
			
			//open up browser to authenticate the user
			try {
				myDesktop.browse(url.toURI());
				JOptionPane.showMessageDialog(this,"Please authenticate in the browser!\nThen press ok!");
			} catch (Exception e)
			{
				JOptionPane.showMessageDialog(this, "Please authenticate at the url:\n" + url.toExternalForm()+"\nAnd press OK to continue!");
			}
			
            try {
            	auth = authInterface.getToken(frob);
                String rep = "Authentication success: \n"+
                			// This token can be used until the user revokes it.
                			"Token: " + auth.getToken() + "\n" +
                			"nsid: " + auth.getUser().getId() + "\n" +
                			"Realname: " + auth.getUser().getRealName() + "\n" +
                			"Username: " + auth.getUser().getUsername() + "\n" +
                			"Permission: " + auth.getPermission().getType() + "\n";
                authenticated = true;
                //set global authentication context hidden api call
                requestContext.setAuth(auth);
                authLabel.setText("Authentication Status: Authenticated!");
                AuthenticateMenuItem.setEnabled(false);
                JOptionPane.showMessageDialog(this,rep);
                
            } catch (Exception e) {
                JOptionPane.showMessageDialog(this,
                							  "Authentication Failed:\n"+e.getMessage(),
                							  "Failed to Authenticate",
                							  JOptionPane.ERROR_MESSAGE);
                authLabel.setText("Authentication Status: Failed!");
                e.printStackTrace();
            }
    	}
    }
    
    //resets the text area
    private void resetText(String text)
    {
      	viewPane.setText(text);
    	viewPane.setCaretPosition(0);
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables 
    private TravelJournal journal;
    private javax.swing.JMenuItem AuthenticateMenuItem;
    private javax.swing.JMenuItem OpenMenuItem;
    private javax.swing.JMenuItem QuitMenuItem;
    private javax.swing.JMenuItem UploadMenuItem1;
    private javax.swing.JMenuItem UploadMenuItem2;
    private javax.swing.JMenuItem ClearSearchsMenuItem; 
    private javax.swing.JLabel authLabel;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JPopupMenu popupMenu;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JScrollPane jScrollPane1;
    private MyPictureCanvas pictureCanvas;
    private javax.swing.JTree tripTree;
    private DefaultMutableTreeNode treeTop;
    private JScrollPane scrollPane;
    private javax.swing.JButton searchButton;
    private java.awt.TextField searchField;
    private JEditorPane viewPane;
    private DefaultMutableTreeNode rootNode;
    private DefaultTreeModel treeModel;
    private TreeMap<String, ? extends Collection<Picture>> albumHash;
    private TreeMap<String, ? extends Collection<HtmlAble>> locationHash;
    private TreeMap<String, ? extends Collection<HtmlAble>> placesHash;
    private TreeMap<String, ? extends Collection<HtmlAble>> peopleHash;
    private TreeMap<Picture.MyDate, ? extends Collection<HtmlAble>> datesHash;
    private TreeMap<String, Collection<HtmlAble>> searchHash;
    private Object selectedNode;
    private Flickr myFlickr;
    private RequestContext requestContext;
    private boolean authenticated = false;
    private Auth auth;
    private DefaultMutableTreeNode searchNode;
    private static final String picturesString = "Pictures";
    private static final String journalString = "Travel Journal";
    private static final String albumsString = "Albums";
    private static final String locationsString = "Locations";
    private static final String placesString = "Places";
    private static final String plansString = "Travel Plans";
    private static final String peopleString = "People";
    private static final String dateString = "Dates";
    private static Desktop myDesktop = Desktop.getDesktop();
    private static ImageIcon flickrPic = new ImageIcon("pics/flickr.png");
    private static ImageIcon errorPic = new ImageIcon("pics/error.png");
    
    // End of variables declaration//GEN-END:variables
	
    
}
